

-- Default values.
Default( "BaseFightTime", 300 )
Default( "AddFightTime", 600 )
Default( "BuildTime", 600 )

// Returns the number of generators total/alive/dead.
function GM:GeneratorStats()
	local total = 0
	local dead = 0
	for _, gen in pairs( ents.FindByClass( "inc_generator" ) ) do
		total = total + 1
		if ( gen:IsDestroyed() ) then dead = dead + 1 end
	end
	return total, total - dead, dead
end

-- Don't allow the generator to be damaged either in build time, or by players.
function GM:AllowGeneratorDamage( ent, info )
	if ( self:IsBuild() ) then return false end
	if ( info:GetAttacker():IsPlayer() ) then return false end
end
GM:AddHook( "GeneratorShouldTakeDamage", "AllowGeneratorDamage" )

-- Some basic effects when a generator is destroyed.
function GM:GeneratorDestroyedEffects( ent )
	local effect = EffectData()
		effect:SetStart( ent:GetPos() )
		effect:SetOrigin( ent:GetPos() )
	util.Effect( "Explosion", effect )
	
	local ball = ents.Create( "prop_combine_ball" )
		ball:SetPos( ent:GetPos() )
	ball:Spawn()
	ball:Fire( "Explode", "", 0 )
	
	local effect = EffectData()
		effect:SetStart( ent:GetPos() )
		effect:SetOrigin( ent:GetPos() )
	util.Effect( "Sparks", effect )
	
	--ent:SetMaterial( "models/debug/debugwhite" )
	ent:SetColor( Color( 20, 20, 20 ) )
end
GM:AddHook( "GeneratorDestroyed", "GeneratorDestroyedEffects" )

-- Sets the round time based on number of generators remaining.
function GM:GeneratorsRoundTime()
	if ( self:IsFight() ) then
		local all = ents.FindByClass( "inc_generator" )
		
		-- Get number of dead generators.
		local total, alive, dead = self:GeneratorStats()
		
		-- Set the round time based on the number of generators left.
 		local deadPercent = dead / total
 		self:SetRoundTimer( self.BaseFightTime + ( self.AddFightTime * deadPercent ), true )
 		self:SetRoundTimer( self.BaseFightTime, true )
	elseif ( self:IsBuild() ) then
		self:SetRoundTimer( self.BuildTime, true )
	end
end
GM:AddHook( "RoundChanged", "GeneratorsRoundTime" )

-- Increases remaining fight round time if a generator is destroyed.

function GM:GeneratorDestroyedTimePenalty()
	if ( self:IsBuild() ) then return end
	local total, alive, dead = self:GeneratorStats()
	
	local percentshield = self:GetRoundLength() / self:GetRoundTimer()
	
	printd( "round length left", self:GetRoundLength(), "total length", self:GetRoundTimer() )
	
	//self:SetRoundTimer( self:GetRoundTimer() * ( ( alive + 1 ) / alive ) )
	//self:SetRoundLength( self:GetRoundTimer() * percentshield ) // Keep shield % the same.
end
GM:AddHook( "GeneratorDestroyed", "GeneratorDestroyedTimePenalty")

function GM:GeneratorDestroyedNPCObliteration(ent)
	for _,npc in pairs (ents.FindByClass ("npc_*")) do
		local length = (npc:GetPos() - ent:GetPos()):Length()
		if length < 512 then
			timer.Simple(length / 1100, function() self:PhysgunOwnsNPCs (nil, npc) end)--nil as there's no player being credited
		end
	end
end

GM:AddHook( "GeneratorDestroyed", "GeneratorDestroyedNPCObliteration")

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// THIS NEEDS FIXING PROBABLY! :D
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
--[[function GM:NPCsTargetGenerators( npc, spawner )
	if ( !spawner.TargetGenerator || spawner.TargetGenerator:Health() <= 0 ) then
		local spawnerPos = spawner:GetPos()
		local generators = ents.FindByClass( "inc_generator" )
		table.sort( generators, function( a, b ) return a:GetPos():Distance( spawnerPos ) < b:GetPos():Distance( spawnerPos ) end )
		for _, gen in ipairs( generators ) do
			if ( gen:Health() > 0 ) then spawner.TargetGenerator = gen break end
		end
	end
	if ( !spawner.TargetGenerator ) then return end
	
	npc:SetLastPosition( spawner.TargetGenerator:GetPos() )
	npc:SetTarget( spawner.TargetGenerator )
	npc:SetSchedule( SCHED_RUN_FROM_ENEMY )
end
GM:AddHook( "NPCSpawned", "NPCsTargetGenerators" )
]]